package com.doris.media.picker.model

import android.graphics.Color
import android.os.Parcel
import android.os.Parcelable
import com.doris.media.picker.R
import java.util.*
import kotlin.collections.ArrayList

object MediaPickerConfig {
    const val TYPE_IMAGE = 0x1
    const val TYPE_VIDEO = 0x2
    const val TYPE_AUDIO = 0x3

    const val MEDIA_PICKER = "MediaPickerOptions"
    const val MEDIA_PICKER_DATA = "MediaPickerData"
    const val MEDIA_PICKER_MIME_TYPE = "MediaPickerMimeType"

    const val MEDIA_PICKER_PREVIEW = "MediaPickerPreviewOptions"

    const val STATUS_THEME_DARK = "Dark"
    const val STATUS_THEME_LIGHT = "Light"

    const val MEDIA_PICKER_RESULT_OK = 0x1000
    const val MEDIA_PICKER_DEFAULT_REQUEST_CODE = 0x1001
}

object MediaMimeType {
    const val IMAGE_PNG = "image/png"
    const val IMAGE_JPG = "image/jpg"
    const val IMAGE_JPEG = "image/jpeg"
    const val IMAGE_WEBP = "image/webp"
    const val IMAGE_BMP = "image/bmp"
    const val IMAGE_GIF = "image/gif"

    @JvmField
    val IMAGE_DEFAULT = arrayListOf(
        IMAGE_PNG, IMAGE_JPG, IMAGE_JPEG, IMAGE_WEBP, IMAGE_BMP
    )

    @JvmField
    val IMAGE_DEFAULT_AND_GIF = arrayListOf(
        IMAGE_PNG, IMAGE_JPG, IMAGE_JPEG, IMAGE_WEBP, IMAGE_BMP, IMAGE_GIF
    )

    const val VIDEO_MP4 = "video/mp4"
    const val VIDEO_MOV = "video/quicktime"
    const val VIDEO_M4V = "video/m4v"
    const val VIDEO_FLV = "video/x-flv"
    const val VIDEO_GPP3 = "video/3gpp"
    const val VIDEO_AVI = "video/x-msvideo"
    const val VIDEO_WMV = "video/x-ms-wmv"

    @JvmField
    val VIDEO_DEFAULT = arrayListOf(
        VIDEO_MP4, VIDEO_MOV, VIDEO_M4V, VIDEO_FLV, VIDEO_GPP3, VIDEO_AVI, VIDEO_WMV
    )

    const val AUDIO_MPEG = "audio/mpeg"
    const val AUDIO_WAX = "audio/x-wav"
    const val AUDIO_WMA = "audio/x-ms-wma"
    const val AUDIO_OGG = "audio/ogg"
    const val AUDIO_AAC = "audio/aac"
    const val AUDIO_AAC_ADTS = "audio/aac-adts"
    const val AUDIO_FLAC = "audio/flac"
    const val AUDIO_MP4 = "audio/mp4"
    val AUDIO_DEFAULT = arrayListOf(
        AUDIO_MPEG, AUDIO_WAX, AUDIO_WMA, AUDIO_OGG, AUDIO_AAC, AUDIO_AAC_ADTS, AUDIO_FLAC,
        AUDIO_MP4
    )
}

object MediaColumn {
    const val id = "_id"
    const val path = "_data"
    const val size = "_size"
    const val width = "width"
    const val height = "height"
    const val duration = "duration"
    const val mimeType = "mime_type"
    const val dateModified = "date_modified"
}

class MediaModel() : Parcelable {
    var path = ""
    var name = ""
    var width = 0
    var height = 0
    var size = 0L
    var sizeTransform = "0B"
    var duration = 0L
    var durationTransform = "00:00"
    var lastModifed = Calendar.getInstance().timeInMillis
    var type = MediaPickerConfig.TYPE_IMAGE

    constructor(parcel: Parcel) : this() {
        path = parcel.readString() ?: ""
        name = parcel.readString() ?: ""
        width = parcel.readInt()
        height = parcel.readInt()
        size = parcel.readLong()
        sizeTransform = parcel.readString() ?: ""
        duration = parcel.readLong()
        durationTransform = parcel.readString() ?: ""
        lastModifed = parcel.readLong()
        type = parcel.readInt()
    }

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(path)
        parcel.writeString(name)
        parcel.writeInt(width)
        parcel.writeInt(height)
        parcel.writeLong(size)
        parcel.writeString(sizeTransform)
        parcel.writeLong(duration)
        parcel.writeString(durationTransform)
        parcel.writeLong(lastModifed)
        parcel.writeInt(type)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<MediaModel> {
        override fun createFromParcel(parcel: Parcel): MediaModel {
            return MediaModel(parcel)
        }

        override fun newArray(size: Int): Array<MediaModel?> {
            return arrayOfNulls(size)
        }
    }

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false

        other as MediaModel

        if (path != other.path) return false

        return true
    }

    override fun hashCode(): Int {
        return path.hashCode()
    }
}

class MediaPickerParameter() : Parcelable {
    var statusTheme = MediaPickerConfig.STATUS_THEME_LIGHT

    var backIcon = R.mipmap.media_picker_back
    var backText = ""
    var backTextColorRes = R.color.media_picker_topbar_text_btn_color

    var title = ""
    var titleColorRes = R.color.topBarTitle

    var sureIcon = 0
    var sureText = ""
    var sureTextColorRes = R.color.media_picker_topbar_text_btn_color

    var topBarColorRes = R.color.topBar
    var topBarRes = 0

    var pageColor = Color.WHITE
    var pageRes = 0

    var tipColor = Color.parseColor("#666666")
    var progressColorRes = R.color.colorAccent
    var permissionBtnColorRes = R.color.colorAccent
    var permissionBtnBorderColorRes = R.color.colorAccent

    var pageSize = 24
    var spanCount = 3
    var isLight = false
    var showNum = false
    var needPreview = true
    var numBorderColorRes = R.color.colorPrimary
    var audioIconColorRes = R.color.colorPrimary

    var min = 1
    var max = 1
    var minSize = 1024
    var maxSize = -1
    var folder = ""
    var type = MediaPickerConfig.TYPE_IMAGE

    var mimeTyp = ArrayList<String>()
    var pickerData = ArrayList<MediaModel>()

    var requestCode = MediaPickerConfig.MEDIA_PICKER_DEFAULT_REQUEST_CODE

    constructor(parcel: Parcel) : this() {
        statusTheme = parcel.readString() ?: MediaPickerConfig.STATUS_THEME_LIGHT

        backIcon = parcel.readInt()
        backText = parcel.readString() ?: ""
        backTextColorRes = parcel.readInt()

        title = parcel.readString() ?: ""
        titleColorRes = parcel.readInt()

        sureIcon = parcel.readInt()
        sureText = parcel.readString() ?: ""
        sureTextColorRes = parcel.readInt()

        topBarColorRes = parcel.readInt()
        topBarRes = parcel.readInt()

        pageColor = parcel.readInt()
        pageRes = parcel.readInt()

        tipColor = parcel.readInt()
        progressColorRes = parcel.readInt()
        permissionBtnColorRes = parcel.readInt()
        permissionBtnBorderColorRes = parcel.readInt()

        pageSize = parcel.readInt()
        spanCount = parcel.readInt()
        isLight = parcel.readByte() != 0.toByte()
        showNum = parcel.readByte() != 0.toByte()
        needPreview = parcel.readByte() != 0.toByte()
        numBorderColorRes = parcel.readInt()
        audioIconColorRes = parcel.readInt()

        min = parcel.readInt()
        max = parcel.readInt()
        minSize = parcel.readInt()
        maxSize = parcel.readInt()
        folder = parcel.readString() ?: ""
        type = parcel.readInt()

        requestCode = parcel.readInt()
    }

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(statusTheme)

        parcel.writeInt(backIcon)
        parcel.writeString(backText)
        parcel.writeInt(backTextColorRes)

        parcel.writeString(title)
        parcel.writeInt(titleColorRes)

        parcel.writeInt(sureIcon)
        parcel.writeString(sureText)
        parcel.writeInt(sureTextColorRes)

        parcel.writeInt(topBarColorRes)
        parcel.writeInt(topBarRes)

        parcel.writeInt(pageColor)
        parcel.writeInt(pageRes)

        parcel.writeInt(tipColor)
        parcel.writeInt(progressColorRes)
        parcel.writeInt(permissionBtnColorRes)
        parcel.writeInt(permissionBtnBorderColorRes)

        parcel.writeInt(pageSize)
        parcel.writeInt(spanCount)
        parcel.writeByte(if (isLight) 1 else 0)
        parcel.writeByte(if (showNum) 1 else 0)
        parcel.writeByte(if (needPreview) 1 else 0)
        parcel.writeInt(numBorderColorRes)
        parcel.writeInt(audioIconColorRes)

        parcel.writeInt(min)
        parcel.writeInt(max)
        parcel.writeInt(minSize)
        parcel.writeInt(maxSize)
        parcel.writeString(folder)
        parcel.writeInt(type)

        parcel.writeInt(requestCode)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<MediaPickerParameter> {
        override fun createFromParcel(parcel: Parcel): MediaPickerParameter {
            return MediaPickerParameter(parcel)
        }

        override fun newArray(size: Int): Array<MediaPickerParameter?> {
            return arrayOfNulls(size)
        }
    }

    fun statusThemeLight(): MediaPickerParameter {
        this.statusTheme = MediaPickerConfig.STATUS_THEME_LIGHT
        return this
    }

    fun statusThemeDark(): MediaPickerParameter {
        this.statusTheme = MediaPickerConfig.STATUS_THEME_DARK
        return this
    }

    fun backText(backText: String): MediaPickerParameter {
        this.backText = backText
        return this
    }

    fun backIcon(backIcon: Int): MediaPickerParameter {
        this.backIcon = backIcon
        return this
    }

    fun backTextColorRes(backTextColorRes: Int): MediaPickerParameter {
        this.backTextColorRes = backTextColorRes
        return this
    }

    fun title(title: String): MediaPickerParameter {
        this.title = title
        return this
    }

    fun titleColorRes(titleColorRes: Int): MediaPickerParameter {
        this.titleColorRes = titleColorRes
        return this
    }

    fun sureText(sureText: String): MediaPickerParameter {
        this.sureText = sureText
        return this
    }

    fun sureIcon(sureIcon: Int): MediaPickerParameter {
        this.sureIcon = sureIcon
        return this
    }

    fun sureTextColorRes(sureTextColorRes: Int): MediaPickerParameter {
        this.sureTextColorRes = sureTextColorRes
        return this
    }

    fun topBarColorRes(topBarColorRes: Int): MediaPickerParameter {
        this.topBarColorRes = topBarColorRes
        return this
    }

    fun topBarRes(topBarRes: Int): MediaPickerParameter {
        this.topBarRes = topBarRes
        return this
    }

    fun pageColor(pageColor: Int): MediaPickerParameter {
        this.pageColor = pageColor
        return this
    }

    fun pageRes(pageRes: Int): MediaPickerParameter {
        this.pageRes = pageRes
        return this
    }

    fun pageSize(pageSize: Int): MediaPickerParameter {
        this.pageSize = pageSize
        return this
    }

    fun spanCount(spanCount: Int): MediaPickerParameter {
        this.spanCount = spanCount
        return this
    }

    fun showNum(showNum: Boolean): MediaPickerParameter {
        this.showNum = showNum
        return this
    }

    fun needPreview(needPreview: Boolean): MediaPickerParameter {
        this.needPreview = needPreview
        return this
    }

    fun numBorderColorRes(numBorderColorRes: Int): MediaPickerParameter {
        this.numBorderColorRes = numBorderColorRes
        return this
    }

    fun tipColor(tipColor: Int): MediaPickerParameter {
        this.tipColor = tipColor
        return this
    }

    fun progressColorRes(progressColorRes: Int): MediaPickerParameter {
        this.progressColorRes = progressColorRes
        return this
    }

    fun permissionBtnColorRes(permissionBtnColorRes: Int): MediaPickerParameter {
        this.permissionBtnColorRes = permissionBtnColorRes
        return this
    }

    fun permissionBtnBorderColorRes(permissionBtnBorderColorRes: Int): MediaPickerParameter {
        this.permissionBtnBorderColorRes = permissionBtnBorderColorRes
        return this
    }

    fun audioIconColorRes(audioIconColorRes: Int): MediaPickerParameter {
        this.audioIconColorRes = audioIconColorRes
        return this
    }

    fun isLight(isLight: Boolean): MediaPickerParameter {
        this.isLight = isLight
        return this
    }

    fun min(min: Int): MediaPickerParameter {
        this.min = min
        return this
    }

    fun max(max: Int): MediaPickerParameter {
        this.max = max
        return this
    }

    fun minSize(minSize: Int): MediaPickerParameter {
        this.minSize = minSize
        return this
    }

    fun maxSize(maxSize: Int): MediaPickerParameter {
        this.maxSize = maxSize
        return this
    }

    fun folder(folder: String): MediaPickerParameter {
        this.folder = folder
        return this
    }

    fun image(): MediaPickerParameter {
        this.type = MediaPickerConfig.TYPE_IMAGE
        return this
    }

    fun video(): MediaPickerParameter {
        this.type = MediaPickerConfig.TYPE_VIDEO
        return this
    }

    fun audio(): MediaPickerParameter {
        this.type = MediaPickerConfig.TYPE_AUDIO
        return this
    }

    fun requestCode(requestCode: Int): MediaPickerParameter {
        this.requestCode = requestCode
        return this
    }

    fun imageAndGif(): MediaPickerParameter {
        this.mimeTyp = MediaMimeType.IMAGE_DEFAULT_AND_GIF
        return this
    }

    fun mimeTyp(mimeTyp: ArrayList<String>): MediaPickerParameter {
        this.mimeTyp = mimeTyp
        return this
    }

    fun pickerData(pickerData: ArrayList<MediaModel>): MediaPickerParameter {
        this.pickerData = pickerData
        return this
    }
}

class MediaPickerPreviewParameter() : Parcelable {
    var statusTheme = MediaPickerConfig.STATUS_THEME_LIGHT
    var path = ""
    var title = ""

    fun statusTheme(statusTheme: String): MediaPickerPreviewParameter {
        this.statusTheme = statusTheme
        return this
    }

    fun path(path: String): MediaPickerPreviewParameter {
        this.path = path
        return this
    }

    fun title(title: String): MediaPickerPreviewParameter {
        this.title = title
        return this
    }

    constructor(parcel: Parcel) : this() {
        statusTheme = parcel.readString() ?: MediaPickerConfig.STATUS_THEME_LIGHT
        path = parcel.readString() ?: ""
        title = parcel.readString() ?: ""
    }

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(statusTheme)
        parcel.writeString(path)
        parcel.writeString(title)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<MediaPickerPreviewParameter> {
        override fun createFromParcel(parcel: Parcel): MediaPickerPreviewParameter {
            return MediaPickerPreviewParameter(parcel)
        }

        override fun newArray(size: Int): Array<MediaPickerPreviewParameter?> {
            return arrayOfNulls(size)
        }
    }
}